﻿using MatrixWebApiCore.Entity;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Linq;
using System.Linq.Expressions;

namespace MatrixWebApiCore.Common.Data
{
    public class RepositoryBase<T> : IRepository<T> where T : BaseEntity, new()
    {
        private DataContext dbContext;
        private DbSet<T> dbSet;
        public RepositoryBase(DataContext _dbContext)
        {
            dbContext = _dbContext;
            dbSet = dbContext.Set<T>();
        }

        public int Add(T entity)
        {
            dbSet.Add(entity);
            return dbContext.SaveChanges();
        }

        public int Add(IEnumerable<T> entitys)
        {
            foreach (var entity in entitys)
            {
                dbSet.Add(entity);
            }
            return dbContext.SaveChanges();
        }

        public int Update(T entity)
        {
            dbSet.Attach(entity);
            dbContext.Entry(entity).State = EntityState.Modified;
            return dbContext.SaveChanges();
        }

        public int Update(IEnumerable<T> entitys)
        {
            foreach (var entity in entitys)
            {
                dbSet.Attach(entity);
                dbContext.Entry(entity).State = EntityState.Modified;
            }
            return dbContext.SaveChanges();
        }

        public int Delete(T entity)
        {
            dbSet.Attach(entity);
            dbSet.Remove(entity);
            return dbContext.SaveChanges();
        }
        //public int Delete(object key) {
        //    //T obj =new T(); 
        //    //obj.Id = Convert.ToString(key);
        //    //dbSet.Attach(obj);
        //    //dbSet.Remove(obj);            
        //    ////dbContext.Database.SqlQuery(t, sql, parameters);
        //    //dbContext.Database.SqlQuery<T>("delete from "+ );
        //    return 1;// dbContext.SaveChanges();
        //}

        public int Delete(Expression<Func<T, bool>> where)
        {
            var entitys = this.GetList(where);
            foreach (var entity in entitys)
            {
                dbSet.Remove(entity);
            }
            return dbContext.SaveChanges();
        }
        public T Get(Expression<Func<T, bool>> where)
        {
            return dbSet.Where(where).FirstOrDefault();
        }

        public IQueryable<T> GetList(Expression<Func<T, bool>> where)
        {
            return dbSet.Where(where);
        }

        public IQueryable<T> GetQuery()
        {
            return dbSet;
        }

        public IQueryable<T> GetQuery(Expression<Func<T, bool>> where)
        {
            return dbSet.Where(where);
        }
        //public IEnumerable<T> GetAll()
        //{
        //    return dbSet.AsEnumerable();
        //}
        public IQueryable<T> GetAll()
        {
            return dbSet.AsParallel().AsQueryable();
            //return dbSet.AsQueryable();
        }

        public T GetAsNoTracking(Expression<Func<T, bool>> where)
        {
            return dbSet.Where(where).AsNoTracking().FirstOrDefault();
        }

        public IQueryable<T> GetManyAsNoTracking(Expression<Func<T, bool>> where)
        {
            return dbSet.AsNoTracking().Where(where);
        }

        public IQueryable<T> GetAllAsNoTracking()
        {
            return dbSet.AsNoTracking();
        }

        public bool Any(Expression<Func<T, bool>> @where)
        {
            return dbSet.Any(where);
        }

        public int Count(Expression<Func<T, bool>> @where)
        {
            return dbSet.Count(where);
        }

        ///// <summary>
        ///// 执行查询语句
        ///// </summary>
        ///// <typeparam name="TS"></typeparam>
        ///// <param name="sql"></param>
        ///// <param name="parameters">参数</param>
        ///// <returns>泛型集合</returns>
        //public DbRawSqlQuery<TS> SqlQuery<TS>(string sql, params SqlParameter[] parameters)
        //{
        //    return dbContext.Database.SqlQuery<TS>(sql, parameters);
        //}
        ///// <summary>
        ///// 执行查询语句
        ///// </summary>
        ///// <typeparam name="T"></typeparam>
        ///// <param name="sql"></param>
        ///// <param name="parameters">参数</param>
        //public DbRawSqlQuery SqlQuery(Type t, string sql, params SqlParameter[] parameters)
        //{
        //    return dbContext.Database.SqlQuery(t, sql, parameters);
        //}
        ///// <summary>
        ///// 执行DML语句
        ///// </summary>
        ///// <param name="sql"></param>
        ///// <param name="parameters"></param>
        //public void ExecuteSql(string sql, params SqlParameter[] parameters)
        //{
        //    dbContext.Database.ExecuteSqlCommand(TransactionalBehavior.EnsureTransaction, sql, parameters);
        //}

    }
}
